﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace pinlib.functions
{
    /// <summary>
    /// Wrapper for the PSAPI
    /// The process status application programming interface (PSAPI) is a helper library that makes it easier for you to obtain information about processes and device drivers.
    /// </summary>
    /// <remarks>PSAPI.dll</remarks>
    /// <seealso>http://msdn.microsoft.com/en-us/library/ms684884(v=VS.85).aspx</seealso>
    public class PSAPIM
    {

        /// <summary>
        ///   Removes as many pages as possible from the working set of the specified process
        /// </summary>
        /// <param name = "hProcess">A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or
        ///   PROCESS_QUERY_LIMITED_INFORMATION access right and the PROCESS_SET_QUOTA access right.
        /// </param>
        /// <returns>If the function succeeds, the return value is nonzero</returns>
        /// <seealso cref="NativeMethods.EmptyWorkingSet"/>
        public static Boolean EmptyWorkingSetM(IntPtr hProcess)
        {
            return PSAPI.EmptyWorkingSet(hProcess);
        }

        /// <summary>
        ///   Retrieves the load address for each device driver in the system
        /// </summary>
        /// <returns>An array containing list of driver addresses</returns>
        /// <seealso cref="NativeMethods.EnumDeviceDrivers"/>
        public static uint[] EnumDeviceDriversM()
        {
            UInt32 lpcbNeeded;

            // First call gets the number of drivers
            PSAPI.EnumDeviceDrivers(null, 0, out lpcbNeeded);

            // To determine how many device drivers were enumerated by the call to EnumDeviceDrivers,
            // divide the resulting value in the lpcbNeeded parameter by sizeof
            uint cb = lpcbNeeded/sizeof (UInt32);

            uint[] lpImageBase = new UInt32[cb];

            // NOW get the addresses
            PSAPI.EnumDeviceDrivers(lpImageBase, cb, out lpcbNeeded);


            return lpImageBase;
        }

        /// <summary>
        ///   Calls the callback routine for each installed pagefile in the system
        /// </summary>
        /// <returns>List of valid page file info</returns>
        /// <remarks>
        ///   Wraps EnumPageFiles and  EnumPageFilesProc
        ///   Creates own ENUM_PAGE_FILE_INFORMATION struct for callback
        /// </remarks>
        public static List<ENUM_PAGE_FILE_INFORMATION> EnumPageFilesM()
        {
            //List to hold all of the pagefile info
            List<ENUM_PAGE_FILE_INFORMATION> pfi = new List<ENUM_PAGE_FILE_INFORMATION>();

            // pin the list
            GCHandle gch = GCHandle.Alloc(pfi);

            // callback
            Callbacks.EnumPageFilesProc efcb = Callbacks.EnumPageFilesProcM;

            try
            {
                PSAPI.EnumPageFiles(efcb, GCHandle.ToIntPtr(gch));

                gch.Free();
            }
            catch (Exception ex)
            {
                int ret = Marshal.GetLastWin32Error();
            }
            pfi.TrimExcess();
            return pfi;
        }


    }
}